﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SDFL.Core.DataStructure
{
    /// <summary>
    /// Compare with generic stack, ObjectStack's Demerits:
    ///     1. Value type(need unboxing/boxing) or Reference type(need explicity cast) will degrade performance;        
    ///     2. Type safety! Conside the code below, it compiles
    ///           ObjectStack stack = new ObjectStack();
    ///           stack.Push(1); 
    ///           string number  = (string)stack.Pop();
    ///        But! when it run, it will get exception "Unable to cast object of type 'System.Int32' to type 'System.String'"
    ///            int i = 1;
    ///            string temp = (string)i; // wrong! Cannot conver type 'int' to 'string'
    /// The difference between c++ template and C# generic
    ///     C++ template, the compiler inserts the code inline, replacing every occurrence of the generic type parameter with the specified type
    ///     This may results in code bloating, increasing both the load time and the memory footprint.  
    /// </summary>
    public class ObjectStack
    {
        readonly int m_Size;
        int m_StatckPointer = 0;
        object[] m_Items;

        public ObjectStack()
            : this(100)
        {
        }

        public ObjectStack(int size)
        {
            m_Size = size;
            m_Items = new object[size];
        }

        public void Push(object item)
        {
            if (m_StatckPointer >= m_Size)
            {
                throw new StackOverflowException();
            }

            m_Items[m_StatckPointer] = item;
            m_StatckPointer++;
        }

        public object Pop()
        {
            m_StatckPointer--;
            if (m_StatckPointer >= 0)
            {
                return m_Items[m_StatckPointer];
            }
            else
            {
                m_StatckPointer = 0;
                throw new InvalidOperationException("Cannot pop an empty stack");
            }
        }
    }
}
